公歷轉(zhuǎn)農(nóng)歷、生肖、干支紀(jì)年、節(jié)氣算法研究和C程序?qū)崿F(xiàn) | 您所在的位置:網(wǎng)站首頁 › 天干地支 算法 › 公歷轉(zhuǎn)農(nóng)歷、生肖、干支紀(jì)年、節(jié)氣算法研究和C程序?qū)崿F(xiàn) |
[本文發(fā)布于https://blog.csdn.net/Stack_/article/details/119980697,未經(jīng)許可不得轉(zhuǎn)載,轉(zhuǎn)載須注明出處] 一、參考文章陽歷轉(zhuǎn)陰歷算法概述 1900年至2100年公歷、農(nóng)歷互轉(zhuǎn)Js代碼 農(nóng)歷的那些事兒(一) 香港天文臺(tái)農(nóng)歷數(shù)據(jù)(txt版) 香港天文臺(tái)農(nóng)歷數(shù)據(jù)(pdf版) 二、關(guān)于農(nóng)歷查閱了大量關(guān)于公歷轉(zhuǎn)農(nóng)歷的博文之后,明確了:所謂的公歷轉(zhuǎn)農(nóng)歷算法即系基于查表法推算。因?yàn)檗r(nóng)歷無明顯規(guī)律,數(shù)據(jù)需要天文臺(tái)觀測(cè)得到,因此無法用公式將公歷轉(zhuǎn)成農(nóng)歷。 如果愿意花錢,可以每天發(fā)請(qǐng)求從特定網(wǎng)站獲取json文本并解析得到這些數(shù)據(jù)。不像時(shí)間和天氣信息,免費(fèi)的農(nóng)歷服務(wù)都是些小網(wǎng)站在提供,有些已經(jīng)停止了這些服務(wù),或者即將關(guān)停。 要制表就需要公歷 - 農(nóng)歷對(duì)照數(shù)據(jù)。 官方網(wǎng)站 - 香港天文臺(tái),僅此一家在網(wǎng)上公開了公歷 - 農(nóng)歷對(duì)照數(shù)據(jù)。 都說內(nèi)地僅紫金山天文臺(tái)有發(fā)布農(nóng)歷數(shù)據(jù),前幾年也發(fā)布了農(nóng)歷國標(biāo),但數(shù)據(jù)在哪呢? 三、制表 (年月日)上面的博文的數(shù)據(jù)均來自香港天文臺(tái),香港天文臺(tái)公開的數(shù)據(jù)范圍為1901年至2100年。 上面的博文的博主已將對(duì)照數(shù)據(jù)按一定格式轉(zhuǎn)成了十六進(jìn)制數(shù)據(jù)制成了表,發(fā)布在博文內(nèi)或者GitHub上。在此感謝那兩位博主。 /* 經(jīng)文本對(duì)比,兩組數(shù)據(jù)的1933年、1996年、2033年、2057年、2060年有區(qū)別 */ /* 遂和天文臺(tái)的數(shù)據(jù)對(duì)比,嗯。。。兩組數(shù)據(jù)你錯(cuò)我就對(duì) */ /* 注意只對(duì)比了有區(qū)別的這幾個(gè)年份,并沒有驗(yàn)證所所有年份數(shù)據(jù) */ /* 1900年的數(shù)據(jù)兩個(gè)都對(duì),第二組只包含了1900年的農(nóng)歷十一、十二月份 */ /* 1900年1月31日為正月初一 */ /* 1901年2月19日為正月初一 */ @ CSDN Tyrion.Mon uint32_t NongLi_Info[] = { 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939 //1933有誤 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999 //1996有誤 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059 //2057有誤 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069 //2060有誤 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099 0x0d520 //2100 }; uint32_t LUNAR_INFO[] = { 0x00010, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929 0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029 0x05aa0, 0x076a3, 0x096d0, 0x026fb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039 //2033有誤 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06aa0, 0x1a6c4, 0x0aae0, //2050-2059 0x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099 0x0d520 //2100 };每個(gè)32位數(shù)據(jù)各代表一年,其中bit0 - bit16共17位有意義。 位含義bit [3:0]數(shù)值范圍為0 - C 。0 代表此年不存在閏月,非零表示此年有閏月,具體數(shù)值 1 - C 表示閏月月份bit [15:4]bit 15 - bit 4 分別代表此年的1 - 12月,為 0 表示此月為小月(29日),為 1 表示大月(30日)bit16在bit [3:0] 為 0 時(shí)忽略;其值僅在bit [3:0]不為 0 時(shí)有效,為1時(shí)表示該年閏月為大月,為 0 時(shí)表小月 閏年閏月每隔開兩三年出現(xiàn)一次閏年,閏年比非閏年多出一個(gè)月,例如某年為閏年,閏月月份為5月,則在5月和6月之間增加一個(gè)閏月,稱為閏5月某年閏月為大月還是小月需要根據(jù)bit16確定 四、干支紀(jì)年根據(jù) 天干 :甲、乙、丙、丁、戊、己、庚、辛、壬、癸 以及 地支 : 子(鼠)、丑(牛)、寅(虎)、卯(兔)、辰(龍)、巳(蛇)、午(馬)、未(羊)、申(猴)、酉(雞)、戌(狗)、亥(豬) 混合編排,60年一個(gè)輪回。 以立春還是正月初一作為干支紀(jì)年上一年和下一年的界限,眾說紛紜。小米手機(jī)的日歷是以正月初一作為界限。 1901年和2021年都是辛丑年,辛丑條約距今已120年。 參考文章 二十四節(jié)氣的日期數(shù)學(xué)計(jì)算公式 計(jì)算公式基本都與這一篇相同,20世紀(jì)與22世紀(jì)的數(shù)據(jù)不全。 六、程序?qū)崿F(xiàn)實(shí)現(xiàn)了根據(jù)公歷年月日計(jì)算出農(nóng)歷月日、生肖、干支紀(jì)年、節(jié)氣,在VS CODE上驗(yàn)證過一小部分,不保證不會(huì)出錯(cuò)。 #include #include #include uint32_t LUNAR_INFO[] = {@ CSDN Tyrion.Mon 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, //1900-1909 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, //1910-1919 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, //1920-1929 0x06566, 0x0d4a0, 0x0ea50, 0x16a95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, //1930-1939 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, //1940-1949 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06aa0, 0x1a6c4, 0x0aae0, //2050-2059 0x092e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099 0x0d520 //2100 }; typedef struct { uint16_t year; uint8_t month; uint8_t date; uint8_t week; uint8_t hour; uint8_t minute; uint8_t second; } Solar_t; //公歷 typedef struct { uint8_t has_leap_month; // 1 此年有閏月, 0 無 /* 如果有閏月下面2個(gè)才有意義 */ uint8_t leapWhichMonth; // 此年閏月是哪個(gè)月份 uint8_t leapMonthis_30days; // 1 此年閏大月, 0 閏小月 uint8_t month; // 當(dāng)前農(nóng)歷月份 uint8_t is_leap_month; // 1 當(dāng)前農(nóng)歷月是閏月 0非閏月 uint8_t date; // 當(dāng)前農(nóng)歷日 uint8_t animal; // 此農(nóng)歷年生肖 1 - 12 : 鼠 - 豬 uint8_t tian_gan; // 1-10甲、乙、丙、丁、戊、己、庚、辛、壬、癸 uint8_t di_zhi; // 1-12子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥 } Lunar_t; //農(nóng)歷 /** * @brief 計(jì)算公歷年份是閏還是平 * @note * @param * @retval * @author PWH @ CSDN Tyrion.Mon * @date 2021/6 */ uint8_t IsLeapYear(uint16_t year) { if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) return 1; //是閏年 return 0; //是平年 } /** * @brief 計(jì)算公歷兩個(gè)日期的間隔天數(shù) * @note Solar2的年月日必須晚于Solar1或相等 * @param * @retval * @author PWH @ CSDN Tyrion.Mon * @date 2021/6 */ uint32_t Calc_Solar_DateInterval(Solar_t *Solar1, Solar_t *Solar2) { int16_t i = 0; uint8_t MonthDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; uint32_t TotalDays1 = 0; //Solar1 uint32_t TotalDays2 = 0; //Solar2 uint32_t TotalDays = 0; //記錄間隔總天數(shù) /* 計(jì)算從Solar1->year 1月1日到Solar1->month Solar2->date的總天數(shù) */ MonthDays[1] = (IsLeapYear(Solar1->year) ? 29 : 28); for (i = 1; i month; i++) { TotalDays1 += MonthDays[i - 1]; //累計(jì)1月到month-1月的天數(shù) } TotalDays1 += Solar1->date; //最后加上month月已達(dá)天數(shù),和值即為本年1月1日到輸入日期的天數(shù) /* 計(jì)算從Solar2->year 1月1日到Solar2->month Solar2->date的總天數(shù) */ MonthDays[1] = (IsLeapYear(Solar2->year) ? 29 : 28); for (i = 1; i month; i++) { TotalDays2 += MonthDays[i - 1]; } TotalDays2 += Solar2->date; /* 如果為同一年 */ if (Solar1->year == Solar2->year) { TotalDays = TotalDays2 - TotalDays1; } else { /* 計(jì)算兩個(gè)年份之間的年份的總天數(shù) */ for (i = Solar1->year + 1; i year; i++) { TotalDays += (IsLeapYear(i) ? 366 : 365); } /* Solar1->year剩余天數(shù) + 兩年之間年份總天數(shù) + Solar2->year已過天數(shù) */ TotalDays += ((IsLeapYear(Solar1->year) ? 366 : 365) - TotalDays1 + TotalDays2); } printf("TotalDays = %d\r\n", TotalDays); return TotalDays; } /** * @brief 計(jì)算此農(nóng)歷年是否有閏月 * @note * @param * @retval -1 輸入錯(cuò)誤 * 0 無閏月 * 1 有閏月 * @author PWH @ CSDN Tyrion.Mon * @date 2021/6 */ int8_t Calc_thisLunarYear_HasLeapMonth(uint16_t SolarYear, Lunar_t *Lunar) { if (SolarYear 2100) return -1; /* 為 0 或者大于12, 無閏月 */ if ((LUNAR_INFO[SolarYear - 1900] & 0x0000000f) == 0 || (LUNAR_INFO[SolarYear - 1900] & 0x0000000f) > 12) { Lunar->has_leap_month = 0; return 0; } /* 存在閏月 */ Lunar->has_leap_month = 1; Lunar->leapWhichMonth = LUNAR_INFO[SolarYear - 1900] & 0x0000000f; // bit3-bit0 該年閏月月份 Lunar->leapMonthis_30days = (LUNAR_INFO[SolarYear - 1900] >> 16) & 0x00000001; // bit16 閏月為大還是小 1大0小 return 1; } /** * @brief 計(jì)算此年農(nóng)歷月(非閏月)的天數(shù) * @note * @param * @retval -1 輸入錯(cuò)誤 * 正確值為29或30 * @author PWH @ CSDN Tyrion.Mon * @date 2021/6 */ int8_t Calc_thisLunarMonth_Days(uint16_t SolarYear, uint8_t LunarMonth) { if (SolarYear 2100) return -1; if (LunarMonth 12) return -1; /* 農(nóng)歷1月bit15, 2月bit14,12月bit4 */ if ( ( LUNAR_INFO[SolarYear - 1900] >> ((12 - LunarMonth) + 4) ) & 0x00000001 ) { return 30; } else { return 29; } } /** * @brief 根據(jù)間隔天數(shù)計(jì)算農(nóng)歷月日 * @note 1900/1/31為正月初一,鼠年,以此為起點(diǎn) * @param * @retval * @author PWH @ CSDN Tyrion.Mon * @date 2021/6 */ int8_t Calc_Lunar_From_DateInterval(uint32_t DateInterval, Lunar_t *LU) { uint16_t SolarYear = 1900; uint32_t DI_temp = 0; int8_t err; LU->has_leap_month = 0; LU->leapWhichMonth = 0; LU->leapMonthis_30days = 0; LU->is_leap_month = 0; //1900農(nóng)歷1月非閏月 LU->month = 1; //1900正月初一始 LU->date = 1; LU->animal = 1; //鼠 LU->tian_gan = 7; //庚 LU->di_zhi = LU->animal; //子 while (1) { /* 查詢此年是否存在閏月,閏月為閏幾月,閏大月還是閏小月 */ err = Calc_thisLunarYear_HasLeapMonth(SolarYear, LU); if (err == -1) return -1; //輸入?yún)?shù)有誤 /* 如果當(dāng)前月為閏月 */ if (LU->is_leap_month == 1) { /* 為大月,則加30日,否則29日 */ DI_temp += LU->leapMonthis_30days ? 30 : 29; } else /* 當(dāng)前月非閏月 */ { /* 查詢非閏月月份的天數(shù) */ DI_temp += Calc_thisLunarMonth_Days(SolarYear, LU->month); } /* 總天數(shù)已達(dá), 當(dāng)前月即是目標(biāo)農(nóng)歷月 */ if (DI_temp >= DateInterval) { /* 如果當(dāng)前月為閏月 */ if (LU->is_leap_month == 1) { LU->date = (LU->leapMonthis_30days ? 30 : 29) - (DI_temp - DateInterval); } else { LU->date = Calc_thisLunarMonth_Days(SolarYear, LU->month) - (DI_temp - DateInterval); } return 1; } /* 未達(dá) */ /* 此年有閏月 并且今年未到過閏月 */ if ((LU->has_leap_month == 1) && (LU->is_leap_month == 0)) { /* 如果此年閏月月份和當(dāng)前月一樣, 此時(shí)應(yīng)該在當(dāng)前月和下一個(gè)月之間插入一個(gè)閏月 */ /* 因?yàn)樯厦娴牟襟E已累加了閏月前一個(gè)月份的天數(shù),所以直接跳到閏月,并標(biāo)記當(dāng)前月為閏月 */ if (LU->leapWhichMonth == LU->month) { LU->is_leap_month = 1; //標(biāo)記現(xiàn)在是閏月,如果當(dāng)前月是5月,匹配上了,那這個(gè)閏月就是閏5月 printf("SolarYear %d LEAP MONTH is %d\r\n", SolarYear, LU->leapWhichMonth); } else { LU->month += 1; } } /* 此年有閏月且今個(gè)月為閏月 或者 此年無閏月 */ else if ( ((LU->has_leap_month == 1) && (LU->is_leap_month == 1)) || (LU->has_leap_month == 0) ) { LU->is_leap_month = 0; //閏月下一個(gè)月為非閏月 LU->month += 1; } /* 溢出處理, 生肖, 天干地支 */ if (LU->month > 12) { if (++SolarYear > 2100) return -1; LU->month = 1; if (++LU->animal > 12) { LU->animal = 1; } if (++LU->tian_gan > 10) { LU->tian_gan = 1; } } LU->di_zhi = LU->animal; } } /** * @brief 公歷年月日轉(zhuǎn)農(nóng)歷月日 * @note * @param * @retval * @author PWH @ CSDN Tyrion.Mon * @date 2021/6 */ int8_t Solar2Lunar(Solar_t *so, Lunar_t *lu) { Solar_t solar_1900; /* 1900/1/31為正月初一,鼠年,以此為起點(diǎn) */ solar_1900.year = 1900; /* 不 */ solar_1900.month = 1; /* 要 */ solar_1900.date = 31; /* 改 */ return Calc_Lunar_From_DateInterval(Calc_Solar_DateInterval(&solar_1900, so) + 1, lu); } /** * @brief 計(jì)算某個(gè)公歷年的24節(jié)氣對(duì)應(yīng)日期 * @note 2月 立春 雨水 * 3月 驚蟄 春分 * 4月 清明 谷雨 * 5月 立夏 小滿 * 6月 芒種 夏至 * 7月 小暑 大暑 * 8月 立秋 處暑 * 9月 白露 秋分 * 10月 寒露 霜降 * 11月 立冬 小雪 * 12月 大雪 冬至 * 1月 小寒 大寒 * @param * @retval * @author PWH @ CSDN Tyrion.Mon * @date 2021/6 */ int8_t Calc_24SolarTerms(uint16_t SolarYear, uint8_t *Array_24SolarTermDate) { uint8_t i = 0; uint8_t Y = SolarYear % 100; //年份后兩位 double D = 0.2422; double C_20xx[] = //21世紀(jì)24個(gè)節(jié)氣的C值 { 3.87, 18.73, 5.63, 20.646, 4.81, 20.1, 5.52, 21.04, 5.678, 21.37, 7.108, 22.83, 7.5, 23.13, 7.646, 23.042, 8.318, 23.438, 7.438, 22.36, 7.18, 21.94, 5.4055, 20.12 }; if (SolarYear 2099) return -1; for (i = 0; i Array_24SolarTermDate[i] -= 1; //例外:2026年計(jì)算得出的雨水日期應(yīng)調(diào)減一天為18日。 } else if (SolarYear == 2084 && i == 3) { Array_24SolarTermDate[i] += 1; //例外:2084年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 1911 && i == 6) { Array_24SolarTermDate[i] += 1; //例外:1911年的計(jì)算結(jié)果加1日 } else if (SolarYear == 2008 && i == 7) { Array_24SolarTermDate[i] += 1; //例外:2008年的計(jì)算結(jié)果加1日 } else if (SolarYear == 1902 && i == 8) { Array_24SolarTermDate[i] += 1; //例外:1902年的計(jì)算結(jié)果加1日 } else if (SolarYear == 1928 && i == 9) { Array_24SolarTermDate[i] += 1; //例外:1928年的計(jì)算結(jié)果加1日。 } else if ((SolarYear == 1925 || SolarYear == 2016) && i == 10) { Array_24SolarTermDate[i] += 1; //例外:1925年和2016年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 1922 && i == 11) { Array_24SolarTermDate[i] += 1; //例外:1922年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 2002 && i == 12) { Array_24SolarTermDate[i] += 1; //例外:2002年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 1927 && i == 14) { Array_24SolarTermDate[i] += 1; //例外:1927年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 1942 && i == 15) { Array_24SolarTermDate[i] += 1; //例外:1942年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 2089 && i == 17) { Array_24SolarTermDate[i] += 1; //例外:2089年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 2089 && i == 18) { Array_24SolarTermDate[i] += 1; //例外:2089年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 1978 && i == 19) { Array_24SolarTermDate[i] += 1; //例外:1978年的計(jì)算結(jié)果加1日。 } else if (SolarYear == 1954 && i == 20) { Array_24SolarTermDate[i] += 1; //例外:1954年的計(jì)算結(jié)果加1日。 } else if ((SolarYear == 1918 || SolarYear == 2021) && i == 21) { Array_24SolarTermDate[i] -= 1; //例外:1918年和2021年的計(jì)算結(jié)果減1日。 } else if (SolarYear == 1982 && i == 22) { Array_24SolarTermDate[i] += 1; //例外:1982年計(jì)算結(jié)果加1日,2019年減1日。 } else if (SolarYear == 2019 && i == 22) { Array_24SolarTermDate[i] -= 1; //例外:1982年計(jì)算結(jié)果加1日,2019年減1日。 } else if (SolarYear == 2082 && i == 23) { Array_24SolarTermDate[i] += 1; //例外:2082年的計(jì)算結(jié)果加1日 } } return 1; } int main(void) { uint8_t i; Solar_t solar_1; Lunar_t Lunar_1; uint8_t Array_24SoTermDate[24]; solar_1.year = 1901; solar_1.month = 9; solar_1.date = 4; Solar2Lunar(&solar_1, &Lunar_1); printf("has_leap_month = %d\r\n", Lunar_1.has_leap_month); printf("leapWhichMonth = %d\r\n", Lunar_1.leapWhichMonth); printf("leapMonthis_30days = %d\r\n", Lunar_1.leapMonthis_30days); printf("month = %d\r\n", Lunar_1.month); printf("is_leap_month = %d\r\n", Lunar_1.is_leap_month); printf("date = %d\r\n", Lunar_1.date); printf("animal = %d\r\n", Lunar_1.animal); printf("tiangan = %d, dizhi = %d\r\n", Lunar_1.tian_gan, Lunar_1.di_zhi); if (Calc_24SolarTerms(2008, Array_24SoTermDate) != -1) { for (i = 0; i |
今日新聞 |
推薦新聞 |
專題文章 |
CopyRight 2018-2019 實(shí)驗(yàn)室設(shè)備網(wǎng) 版權(quán)所有 |